<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head>
<!--
Possible channels of interference, explored in this document or general properties we would like the portlet markup fragment to have
1. A global variable created in HEAD
2. A global built in object (e.g. navigator)
3. (Later)Access Keys, Tab Index (who wins if there is a conflict, eg. override Alt+F)
4. Dynamically modifying the DOM, Disallowed HTML Tags
5. Direct access by traversing the DOM Tree
6. (Later)Shared prototype objects
7. (Later)Cookies (essentially a global built in object which is writeable)
8. Reference to 'this'
9. The shared namespace, shared scope (understand how the scope works)
10. Dynamically add javascript event handlers.
11. Use of 'eval', self-modifying code
12. Shared style sheets
13. Access to shared library functions, eg. parseInt()
14. Maintain general structural integrity of the document - e.g. tags should appear where they should according to the DTD

TODO:
// creating a new function using a prototype, can the new function access the local variable of the event handler which creates the new function?
// when you create a new function in different html contexts, what is the value of this?
// The parser automatically inserts HTML Elements, e.g. TBODY in the table. We have to handle that. The swing html parser doesn't recognize TBODY, though.
-->
<style>
 .test{color: red;}
 .odd{background-color: white;}
 .even{background-color: gray;}
</style>
<script language=javascript>
<!--
// 
// 1. A global value that all portlets might need to access (read/write?)
// Global variable that the portal would like the portlets to make use of
// However, this like all other system objects should be made readonly by analysis
var now=new Date,t1=0;
t1=now.getTime();
-->
</script>

<title>Example Portal Page with two Portlets</title>
</head>
<body>

<table>
<tbody>
<tr>
<td>This will maliciously be removed by a portlet if you click on the text in the gray box</td><td>That should be avoided</td>
</tr>
<tr>
<td width="40%" class=odd>
<div>
<!-- Start: Portlet 1 Markup Fragment -->

<script type="text/javascript">
<!--
// 2. Use of a system global object might be required. Such accesses should be made readonly
this.agt = navigator.userAgent.toLowerCase();
this.ie = (this.agt.indexOf("msie") != -1);
if(this.ie) {
	document.write("<p>Sorry, we do not support Internet Explorer");
	document.close();
} else {
	document.write("<p>We applaud your taste in browsers!");
}

// The following line is erased using a style element in the malicious portlet
document.write("<p class=test>The time you started visiting this page is : " + t1 + "</p>");

-->
</script>

<h1>Plan a dinner with friends</h1><br>
<h2>Enter the names of Restaurants in order of descending preference</h2>
<form action="http://www.google.com/search" name=f onsubmit="sub(this);">
<input type=hidden name=hl value=en>
<input type=hidden name=q value="">

<script type="text/javascript">
<!--

var counter=2;
function sub(fm) {
	var qstring = document.f.name1.value + " " + document.f.conf1.value + " restaurant ";
	document.f.q.value = qstring;
	var then = new Date;
	alert("You took " + ((then.getTime()-t1)/1000) + " seconds to submit your preferences.");
	return 1;
}
function createLinkElem(target, str) {
	var moveElem = document.createElement("TD");
	moveElem.appendChild(createLink(target, str));
	return moveElem;
}
function createLink(target,str) {
	var fnt = document.createElement("FONT");
	fnt.setAttribute("size","-1");
	fnt.appendChild(document.createTextNode(str));
	var lnk = document.createElement("A");
	lnk.setAttribute("href","#");

	lnk.setAttribute("onclick",target);


	lnk.appendChild(fnt);
	return lnk;
}
function createInsertNode() {
	var inElem = document.createElement("TR");
	var elem = document.createElement("TD");
	elem.setAttribute("colspan","6");
	elem.setAttribute("align","center");
	var lnk = createLink("insertRow(this);","Insert Row");

	// creating an event handler by directly assigning the value of the onclick property
	lnk.onclick = iRow;
	elem.appendChild(lnk);
	inElem.appendChild(elem);
	return inElem;
}
function iRow() {
	insertRow(this);
}
function mUp() {
	moveUp(this);
}
function boxNode(nm, str) {
	var elem = document.createElement("TD");
	var inp = document.createElement("INPUT");
	inp.setAttribute("maxlength","2048");
	inp.setAttribute("size","55");
	inp.setAttribute("name",nm);
	inp.setAttribute("value","");
	inp.setAttribute("title",str);
	elem.appendChild(inp);
	return elem;
}
function createRow(num) {
	var newElem = document.createElement("TR");

	var lnk = createLinkElem("moveUp(this);", "Move Up");
	
	// creating an event handler using the addEventListener method
	lnk.addEventListener('click', mUp, false);
	newElem.appendChild(lnk);

	var elemChild = document.createElement("TD");
	elemChild.appendChild(document.createTextNode(num));
	newElem.appendChild(elemChild);

	newElem.appendChild(boxNode("name"+num,"Name "+num));
	newElem.appendChild(boxNode("conf"+num,"Location "+num));

	newElem.appendChild(createLinkElem("moveDown(this);","Move Down"));
	newElem.appendChild(createLinkElem("deleteElem(this);","Delete Row"));

	newElem.setAttribute("id","bar");
	newElem.setAttribute("index",num);
	newElem.setAttribute("rowIndex", 5);
	alert(newElem.getAttribute("rowIndex"));
	return newElem;
}
function insertRow(telement) {
	var chld = getRow(telement);
	var par = chld.parentNode;
	var prev = prevRow(chld);

	var numE,num;
	if(prev) {
		numE = prev.cells[1];
		var num = numE.firstChild.nodeValue;
		if(num=="Rank") {
			num = 1;
		} else {
			num = parseInt(numE.firstChild.nodeValue) + 1;
		}
	} else {
		num = 1;
	}
	par.insertBefore(createInsertNode(), chld);
	par.insertBefore(createRow(num), chld);

	chld = nextRow(chld);
	while(chld) {
		incNumber(chld, true);
		chld = nextRow(chld);
	}
	
}
function incNumber(trow, inc) {
	if(trow.cells.length != 6) return;
//	alert("before removing" + trow.getAttribute("id") + " = " + trow.id);
//	trow.id = null;
//	alert("after removing" + trow.getAttribute("id") + " = " + trow.id);
//	alert("before removing" + trow.getAttribute("index") + " = " + trow.index);
//	trow.index = null;
//	alert("after removing" + trow.getAttribute("index") + " = " + trow.index);
	alert(trow.getAttribute("rowIndex"));

	var node = trow.cells[1];
	var num = node.firstChild.nodeValue;
	num = parseInt(num);
	if(inc)	{
		num++;
	} else {
		num--;
	}
	trow.setAttribute("index", num);
	
	node.firstChild.nodeValue=num+".";

	node = trow.cells[2];
	node = node.firstChild;
	node.setAttribute("name","name"+num);
	node.setAttribute("title","Name "+num);

	node = trow.cells[3];
	node = node.firstChild;
	node.setAttribute("name","conf"+num);
	node.setAttribute("title","Location "+num);
}
function prevRow(telement) {
	if(!telement) {
		return null;
	}
	var prev = telement.previousSibling;

	while(prev && prev.nodeName != "TR") {
		prev = prev.previousSibling;
	}
	return prev;
}
function nextRow(telement) {
	if(!telement) {
		return null;
	}
	var next = telement.nextSibling;
	while(next && next.nodeName != "TR") {
		next = next.nextSibling;
	}
	return next;
}
function getRow(telement) {
	var chld = telement.parentNode;
	while(chld.nodeName != "TR") {
		chld = chld.parentNode;
	}
	return chld;
}
function moveUp(telement) {
	var trow = getRow(telement);
	var prev = prevRow(prevRow(trow));
	var par = trow.parentNode;
	if(prevRow(prev)) {
		incNumber(trow,false);
		incNumber(prev,true);
		var next = nextRow(trow);
		var remove = par.removeChild(trow);
		par.insertBefore(remove,prev);

		remove = par.removeChild(prev);
		par.insertBefore(remove,next);
	}
}
function moveDown(telement) {
	var trow = getRow(telement);
	var next = nextRow(nextRow(trow));
	var par = trow.parentNode;
	if(next) {
		incNumber(trow,true);
		incNumber(next,false);
		var follo = nextRow(trow);
		var remove = par.removeChild(trow);
		par.insertBefore(remove,next);

		remove = par.removeChild(next);
		par.insertBefore(remove,follo);
	}
}
function deleteElem(telement) {
	var tr = getRow(telement);
	follow = nextRow(tr);

	var par = tr.parentNode;
	var prev = prevRow(tr);
	par.removeChild(prev);
	par.removeChild(tr);
	while(follow) {
		incNumber(follow, false);
		follow = nextRow(follow);
	}
}

-->
</script>

<table>
<tbody>
<tr>
<td>&nbsp;</td><td align=center>Rank</td> <td align=center>Name of Restaurant</td> <td align=center>Location</td><td>&nbsp;</td><td>&nbsp;</td>
</tr>
<tr><td colspan=6 align=center><a href="#" onclick="insertRow(this);"><font size="-1">Insert Row</font></a></td></tr>
<tr id="bar" rowIndex="5">
<td><a href="#" onclick="moveUp(this);"><font size="-1">Move Up</font></a></td>
<td>1.</td>
<td><input maxlength=2048 size=55 name="name1" value="" title="Name 1"></td>
<td><input maxlength=2048 size=55 name="conf1" value="" title="Location 1"></td>
<td><font size="-1"><a href="#" onclick="moveDown(this);">Move Down</a></font></td>
<td><font size="-1"><a href="#" onclick="deleteElem(this);">Delete Row</a></font>
</tr>
<tr><td colspan=6 align=center><a href="#" onclick="insertRow(this);"><font size="-1">Insert Row</font></a></td></tr>
</tbody>
</table>

<p><center><input type=submit value="Submit Preferences" name=btnI></center>
</form>



<!-- End: Portlet 1 Markup Fragment -->
</div>
</td>


<td width="40%" class=even>
<div>
<!-- Start Portlet 2 Markup Fragment -->

<p id="secret" onclick="malicious(this)">This portlet contains information that is top secret. Thou shalt not read it</p>

<!-- Malicious style element -->
<!--
<style>
  .test{color: white;}
</style>
-->

<script type="text/javascript">
<!--

function malicious(elem) {
	var par = elem.parentNode;
	// Creating a disallowed tag
	var base = document.createElement("BASE");
	base.setAttribute("href","http://www.hacker.com/");
	par.appendChild(base);

	// create a table
//	var tab = document.createElement("TABLE");
//	var tbody = document.createElement("TBODY");
//	var tr = document.createElement("TR");
	var td = document.createElement("TD");
	var txt = document.createTextNode("Text");
	td.appendChild(txt);
//	tr.appendChild(td);
//	tbody.appendChild(tr);
//	tab.appendChild(td);
	par.appendChild(td);
	// TBODY is not automatically inserted


	// Accessing and messing with other parts of the tree
	while(par.nodeName != "TBODY") {
		par = par.parentNode;
	}

	// anything outside the Restricted DOM Spec should be disallowed
	par.firstChild.innerHTML = "This is crazy!";
	alert(par.firstChild);
	par.removeChild(par.firstChild);
	
}
// The following line writes into a shared global variable, and should be stopped
t1 = 1000;

// Write access to system level objects should be disallowed
window.status = "Malicious Portlet";

-->
</script>

<!-- End: Portlet 2 Markup Fragment -->
</div>
</td>
</tbody>
</table>

</body>
</html>